package com.pipi.sso.core.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.pipi.sso.core.exception.DormServiceException;
import com.pipi.sso.core.service.CollegeService;
import com.pipi.sso.core.service.StudentService;
import com.pipi.sso.core.enums.CommonStatusEnum;
import com.pipi.sso.core.enums.DormErrorCodeEnum;
import com.pipi.sso.core.model.CollegeBO;
import com.pipi.sso.core.model.StudentBO;
import com.pipi.sso.core.util.BeanUtils;
import com.pipi.sso.core.util.DateUtil;
import com.pipi.sso.dao.manager.ClassesManager;
import com.pipi.sso.dao.manager.DormitoryAllocationManager;
import com.pipi.sso.dao.manager.StudentManager;
import com.pipi.sso.dao.model.ClassesDO;
import com.pipi.sso.dao.model.DormitoryAllocationDO;
import com.pipi.sso.dao.model.StudentDO;
import com.pipi.sso.dao.query.DormitoryAllocationQuery;
import com.pipi.sso.dao.query.StudentQuery;
import com.pipi.sso.dao.support.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * All rights Reserved, Designed By www.maihaoche.com
 *
 * @Package com.pipi.sso.core.service.impl
 * @date: 2019/3/30 12:02 PM
 * @Copyright: 2017-2020 www.maihaoche.com Inc. All rights reserved.
 */
@Service
@Slf4j
public class StudentServiceImpl implements StudentService {

    @Resource
    private StudentManager studentManager;

    @Resource
    private CollegeService collegeService;

    @Resource
    private ClassesManager classesManager;

    @Resource
    private DormitoryAllocationManager dormitoryAllocationManager;


    @Override
    public PageResult<StudentBO> queryStudentByPage(StudentBO studentBO) {
        StudentQuery studentQuery = buildStudentQuery(studentBO);
        studentQuery.setPageNo(studentBO.getPage());
        studentQuery.setPageSize(studentBO.getLimit());
        try {
            PageResult<StudentDO> studentDOPageResult = studentManager.selectByQueryWithPage(studentQuery);
            if (CollectionUtils.isEmpty(studentDOPageResult.getResult())) {
                return PageResult.createPageResult();
            }
            List<StudentBO> studentBOS = buildStudentBOs(studentDOPageResult.getResult());
            return PageResult.createPageResult(studentBOS, studentDOPageResult.getPageInfo());
        } catch (DormServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error(DormErrorCodeEnum.QUERY_STUDENT_FAIL.getErrMsg() + "studentBO is {}", JSON.toJSONString(studentBO), e);
            throw new DormServiceException(DormErrorCodeEnum.QUERY_STUDENT_FAIL);
        }

    }

    @Override
    public List<StudentBO> queryStudent(StudentBO studentBO) {
        StudentQuery studentQuery = buildStudentQuery(studentBO);
        try {
            List<StudentDO> studentDOS = studentManager.selectByQuery(studentQuery);
            if (CollectionUtils.isEmpty(studentDOS)) {
                return Lists.newArrayList();
            }
            return buildStudentBOs(studentDOS);
        } catch (DormServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error(DormErrorCodeEnum.QUERY_STUDENT_FAIL.getErrMsg() + "studentBO is {}", JSON.toJSONString(studentBO), e);
            throw new DormServiceException(DormErrorCodeEnum.QUERY_STUDENT_FAIL);
        }
    }

    @Override
    public Boolean addStudent(StudentBO studentBO) {
        try {
            // 查找学生是否已经存在
            StudentQuery studentQuery = new StudentQuery();
            studentQuery.createCriteria().andIsDeletedEqualTo
            (CommonStatusEnum.NO.getCode()).andStudentNoEqualTo(studentBO.getStudentNo());
            List<StudentDO> studentDOS = studentManager.selectByQuery(studentQuery);
            if (!CollectionUtils.isEmpty(studentDOS)) {
                throw new DormServiceException(DormErrorCodeEnum.STUDENT_IS_EXIST);
            }

            StudentDO studentDO = BeanUtils.createCloneBean(studentBO, StudentDO.class);
            studentDO.setIsDeleted(CommonStatusEnum.NO.getCode());
            CollegeBO collegeBO = new CollegeBO();
            collegeBO.setCollegeId(studentDO.getCollegeId());
            // 关联学院信息，班级信息
            List<CollegeBO> collegeBOS = collegeService.queryCollege(collegeBO);
            if (!CollectionUtils.isEmpty(collegeBOS)) {
                studentDO.setCollegeName(collegeBOS.get(0).getCollegeName());
            }
            ClassesDO classesDO = classesManager.selectByPrimaryKey(studentBO.getClassId());
            if (Objects.nonNull(classesDO)) {
                studentDO.setProfession(classesDO.getProfession());
                studentDO.setClassesName(classesDO.getClassesName());
            }
            // 保存学生信息
            long num = studentManager.insertSelective(studentDO);
            if (1 != num) {
                throw new DormServiceException(DormErrorCodeEnum.ADD_STUDENT_FAIL);
            }
            return true;
        } catch (DormServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error(DormErrorCodeEnum.ADD_STUDENT_FAIL.getErrMsg() +
                    "studentBO is {}", JSON.toJSONString(studentBO), e);
            throw new DormServiceException(DormErrorCodeEnum.ADD_STUDENT_FAIL);
        }
    }

    @Override
    public Boolean updateStudent(StudentBO studentBO) {
        try {
            StudentDO studentDO = BeanUtils.createCloneBean(studentBO, StudentDO.class);
            studentDO.setGmtModified(new Date());
            CollegeBO collegeBO = new CollegeBO();
            collegeBO.setCollegeId(studentDO.getCollegeId());
            List<CollegeBO> collegeBOS = collegeService.queryCollege(collegeBO);
            if (!CollectionUtils.isEmpty(collegeBOS)) {
                studentDO.setCollegeName(collegeBOS.get(0).getCollegeName());
            }
            ClassesDO classesDO = classesManager.selectByPrimaryKey(studentBO.getClassId());
            if (Objects.nonNull(classesDO)) {
                studentDO.setProfession(classesDO.getProfession());
                studentDO.setClassesName(classesDO.getClassesName());
            }
            int i = studentManager.updateByPrimaryKeySelective(studentDO);
            return 1 == i;
        } catch (DormServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error(DormErrorCodeEnum.UPDATE_STUDENT_FAIL.getErrMsg() + "studentBO is {}", JSON.toJSONString(studentBO), e);
            throw new DormServiceException(DormErrorCodeEnum.UPDATE_STUDENT_FAIL);
        }
    }

    @Override
    public void deleteStudent(List<Long> studentIds) {
        try {

//            StudentDO studentDO = studentManager.selectByPrimaryKey(studentId);
//            if (null == studentDO || CommonStatusEnum.YES.equals(studentDO.getIsDeleted())) {
//                log.error("该数据不存在或已被删除！studentId is {}, studentDO is {}", studentId, JSON.toJSONString(studentDO));
//                throw new DormServiceException(DormErrorCodeEnum.DATA_EXCEPTION);
//            }
            StudentDO studentDO = new StudentDO();
            studentDO.setIsDeleted(CommonStatusEnum.YES.getCode());
            StudentQuery query = new StudentQuery();
            query.createCriteria().andStudentIdIn(studentIds);
            studentManager.updateByQuerySelective(studentDO, query);
            // 将学生的入住宿舍信息删除
            DormitoryAllocationQuery dormitoryAllocationQuery = new DormitoryAllocationQuery();
            dormitoryAllocationQuery.createCriteria().andStudentIdIn(studentIds);
            DormitoryAllocationDO dormitoryAllocationDO = new DormitoryAllocationDO();
            dormitoryAllocationDO.setIsDeleted(CommonStatusEnum.YES.getCode());
            dormitoryAllocationDO.setExitTime(new Date());
            dormitoryAllocationManager.updateByQuerySelective(dormitoryAllocationDO, dormitoryAllocationQuery);
        } catch (DormServiceException e) {
            throw e;
        } catch (Exception e) {
            log.error(DormErrorCodeEnum.DELETE_STUDENT_FAIL.getErrMsg() + "studentIds is {}", JSON.toJSONString(studentIds), e);
            throw new DormServiceException(DormErrorCodeEnum.DELETE_STUDENT_FAIL);
        }
    }

    private StudentQuery buildStudentQuery(StudentBO studentBO) {
        StudentQuery studentQuery = new StudentQuery();
        studentQuery.setOrderByClause("gmt_create desc");
        if (null != studentBO) {
            StudentQuery.Criteria criteria = studentQuery.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode());
            if (null != studentBO.getStudentId()) {
                criteria.andStudentIdEqualTo(studentBO.getStudentId());
            }
            if (StringUtils.isNotBlank(studentBO.getStudentNo())) {
                criteria.andStudentNoLike("%" + studentBO.getStudentNo() + "%");
            }
            if (StringUtils.isNotBlank(studentBO.getStudentName())) {
                criteria.andStudentNameLike("%" + studentBO.getStudentName() + "%");
            }
            if (null != studentBO.getGender()) {
                criteria.andGenderEqualTo(studentBO.getGender());
            }
            if (null != studentBO.getClassId()) {
                criteria.andClassIdEqualTo(studentBO.getClassId());
            }
            if (null != studentBO.getCollegeId()) {
                criteria.andCollegeIdEqualTo(studentBO.getCollegeId());
            }
            if (null != studentBO.getProfession()) {
                criteria.andProfessionLike("%" + studentBO.getProfession() + "%");
            }
        }
        return studentQuery;
    }

    private List<StudentBO> buildStudentBOs(List<StudentDO> studentDOS) {
        if (null == studentDOS) {
            return Lists.newArrayList();
        }
        return studentDOS.stream().map(this::buildStudentBO).collect(Collectors.toList());
    }

    private StudentBO buildStudentBO(StudentDO studentDO) {
        if (studentDO == null) {
            return null;
        }
        StudentBO studentBO = BeanUtils.createCloneBean(studentDO, StudentBO.class);
        studentBO.setGenderDesc(CommonStatusEnum.getGenderDescByCode(studentBO.getGender()));
        studentBO.setDateOfBirthDesc(DateFormatUtils.format(studentDO.getDateOfBirth(), DateUtil.PATTERN_1));
        studentBO.setStudyTimeDesc(DateFormatUtils.format(studentDO.getStudyTime(), DateUtil.PATTERN_1));
        studentBO.setStudentNoAndName(studentBO.getStudentNo() + "-" + studentBO.getStudentName());

        DormitoryAllocationQuery dormitoryAllocationQuery = new DormitoryAllocationQuery();
        dormitoryAllocationQuery.createCriteria().andStudentIdEqualTo(studentBO.getStudentId())
                .andIsDeletedEqualTo(CommonStatusEnum.NO.getCode());
        List<DormitoryAllocationDO> dormitoryAllocationDOS = dormitoryAllocationManager.selectByQuery(dormitoryAllocationQuery);
        if (CollectionUtils.isNotEmpty(dormitoryAllocationDOS)) {
            studentBO.setDormitory(dormitoryAllocationDOS.get(0).getRoomName());
        }
        return studentBO;
    }
}
